"""
流体物性参数计算模块

该模块提供了计算水和水蒸气物性参数的函数，使用CoolProp库进行计算。
包括密度、粘度、导热系数、比热容等物性参数的计算。
"""

from typing import Dict, Union, Optional
import numpy as np
from CoolProp.CoolProp import PropsSI

class FluidProperties:
    """
    流体物性计算类
    
    提供计算水和水蒸气在不同温度和压力下的物性参数的方法。
    使用CoolProp库进行物性计算。
    """
    
    def __init__(self):
        """初始化流体物性计算器"""
        self.fluid = "Water"
        
    def get_properties(self, pressure: float, temperature: float, 
                      phase: str) -> Dict[str, float]:
        """
        计算给定压力和温度下的流体物性
        
        参数:
            pressure: 压力 (Pa)
            temperature: 温度 (K)
            phase: 相态 ('liquid' 或 'vapor')
            
        返回:
            包含以下物性参数的字典:
            - density: 密度 (kg/m³)
            - viscosity: 动力粘度 (Pa·s)
            - conductivity: 导热系数 (W/m·K)
            - specific_heat: 定压比热容 (J/kg·K)
            - enthalpy: 比焓 (J/kg)
        """
        try:
            # 计算基本物性
            density = PropsSI('D', 'P', pressure, 'T', temperature, self.fluid)
            viscosity = PropsSI('V', 'P', pressure, 'T', temperature, self.fluid)
            conductivity = PropsSI('L', 'P', pressure, 'T', temperature, self.fluid)
            specific_heat = PropsSI('C', 'P', pressure, 'T', temperature, self.fluid)
            enthalpy = PropsSI('H', 'P', pressure, 'T', temperature, self.fluid)
            
            return {
                'density': density,
                'viscosity': viscosity,
                'conductivity': conductivity,
                'specific_heat': specific_heat,
                'enthalpy': enthalpy
            }
            
        except Exception as e:
            print(f"Error calculating properties: {str(e)}")
            return None
            
    def get_saturation_properties(self, pressure: float) -> Dict[str, Dict[str, float]]:
        """
        计算给定压力下的饱和状态物性
        
        参数:
            pressure: 压力 (Pa)
            
        返回:
            包含液相和气相饱和物性的字典
        """
        try:
            # 计算饱和温度
            Tsat = PropsSI('T', 'P', pressure, 'Q', 0, self.fluid)
            
            # 计算液相饱和物性
            liquid_props = self.get_properties(pressure, Tsat, 'liquid')
            
            # 计算气相饱和物性
            vapor_props = self.get_properties(pressure, Tsat, 'vapor')
            
            return {
                'temperature': Tsat,
                'liquid': liquid_props,
                'vapor': vapor_props
            }
            
        except Exception as e:
            print(f"Error calculating saturation properties: {str(e)}")
            return None
            
    def calculate_surface_tension(self, temperature: float) -> float:
        """
        计算给定温度下的表面张力
        
        参数:
            temperature: 温度 (K)
            
        返回:
            表面张力 (N/m)
        """
        try:
            # 使用CoolProp计算表面张力
            surface_tension = PropsSI('I', 'T', temperature, 'Q', 0, self.fluid)
            return surface_tension
            
        except Exception as e:
            print(f"Error calculating surface tension: {str(e)}")
            return None
            
    def calculate_heat_transfer_coefficient(self, 
                                         reynolds: float,
                                         prandtl: float,
                                         hydraulic_diameter: float,
                                         conductivity: float) -> float:
        """
        计算对流传热系数（使用Dittus-Boelter关联式）
        
        参数:
            reynolds: 雷诺数
            prandtl: 普朗特数
            hydraulic_diameter: 水力直径 (m)
            conductivity: 导热系数 (W/m·K)
            
        返回:
            对流传热系数 (W/m²·K)
        """
        try:
            # Dittus-Boelter关联式
            nusselt = 0.023 * reynolds**0.8 * prandtl**0.4
            h = nusselt * conductivity / hydraulic_diameter
            return h
            
        except Exception as e:
            print(f"Error calculating heat transfer coefficient: {str(e)}")
            return None
            
    def calculate_friction_factor(self, reynolds: float, 
                                relative_roughness: float) -> float:
        """
        计算摩擦因子（使用Colebrook关联式）
        
        参数:
            reynolds: 雷诺数
            relative_roughness: 相对粗糙度
            
        返回:
            摩擦因子
        """
        try:
            if reynolds < 2300:  # 层流
                return 64 / reynolds
            elif reynolds > 4000:  # 湍流
                # 使用Colebrook关联式的显式近似
                A = -2 * np.log10(relative_roughness/3.7 + 2.51/reynolds)
                f = 1 / (A**2)
                return f
            else:  # 过渡区
                # 线性插值
                f_lam = 64 / 2300
                f_turb = self.calculate_friction_factor(4000, relative_roughness)
                return f_lam + (f_turb - f_lam) * (reynolds - 2300) / 1700
                
        except Exception as e:
            print(f"Error calculating friction factor: {str(e)}")
            return None 